/* 
  在此文件中，根据 DOC 目录下的 index.js 文件生成 js 描述。
*/

const DOC_DIR_NAME = 'doc'
const DATA_DIR_NAME = './src/_data~'
const __dirname = './'

import fs from 'fs'
import path from 'path'
import moment from 'moment'

let cateDesc = fs.readFileSync(path.resolve(__dirname, 'doc/index.json'), 'utf8')
cateDesc = removeBOM(cateDesc)
const categoryDesc = JSON.parse(cateDesc)

function removeBOM(content) {
  if (content.charCodeAt(0) === 0xFEFF) {
    content = content.slice(1)
  }
  return content
}

// 遍历，根据数据读取目录下的 markdown 文件
categoryDesc.forEach(category => {
  const lessInfo = []
  // 如果不存在 alias 字段，则根据 title 字段获取 doc/title 目录下的 markdown 文件；
  const { title, alias } = category
  const categoryDir = alias ? alias : title
  const categoryDirPath = path.resolve(__dirname, DOC_DIR_NAME, categoryDir)
  // 如果目录不存在，创建 
  if (!fs.existsSync(categoryDirPath)) {
    fs.mkdirSync(categoryDirPath)
    // 打印信息
    console.log(`目录 ${categoryDirPath} 不存在，已创建`)
  }
  // 如果 category 没有时间字段则获取目录的创建时间和修改时间
  if (!category.createTime && !category.updateTime) {
    const categoryStat = fs.statSync(categoryDirPath)
    const createTime = categoryStat.birthtime
    const updateTime = categoryStat.mtime
    // 将目录的创建时间和修改时间添加到 category 对象中
    category.createTime = moment(createTime).format('YYYY-MM-DD HH:mm:ss')
    category.updateTime = moment(updateTime).format('YYYY-MM-DD HH:mm:ss')
  }
  let count = 0
  // 读取目录
  const files = fs.readdirSync(categoryDirPath)
  files.forEach((file, index) => {
    if (file.startsWith('~')) return
    const filePath = path.resolve(categoryDirPath, file)
    const fileStat = fs.statSync(filePath)
    const id = `${category.id}-${index}`
    // 如果是文件夹
    if (fs.statSync(filePath).isDirectory()) {
      const filesInDir = fs.readdirSync(filePath)
      const shardInfo = {
        id,
        type: 1, // 与服务端保持一致
        title: file,
        children: []
      }
      // 分片下的 md 文件，一方面，要保存到单独的 json 里，另一方面，要保存到 shardInfo 的 children 里
      filesInDir.forEach((fileInDir, indexInDir) => {
        if (fileInDir.startsWith('~')) return
        const filePathInDir = path.resolve(filePath, fileInDir)
        const idInDir = `${id}-${indexInDir}`
        if (!fileInDir.endsWith('.md')) return
        const fileContentInDir = fs.readFileSync(filePathInDir, 'utf8').replace(/\r\n/g, '\n')
        const { desc, keywords, realContent } = getMeta(fileContentInDir)
        const fileStatInDir = fs.statSync(filePathInDir)
        const title = fileInDir.replace('.md', '')
        const fileInfoInDir = {
          id: idInDir,
          cateId: id,
          title,
          content: realContent,
          metaDesc: desc,
          metaKeywords: keywords,
          createTime: moment(fileStatInDir.birthtime).format('YYYY-MM-DD HH:mm:ss'),
          updateTime: moment(fileStatInDir.mtime).format('YYYY-MM-DD HH:mm:ss')
        }
        // 保存详细信息到文件
        fs.writeFileSync(path.resolve(__dirname, DATA_DIR_NAME, 'articles', `${idInDir}.json`)
          , JSON.stringify(fileInfoInDir, null, 2)
        )
        shardInfo.children.push({ id: idInDir, title })
        count++
      })
      lessInfo.push(shardInfo)
      return
    }
    if (!file.endsWith('.md')) return
    const fileContent = fs.readFileSync(filePath, 'utf8').replace(/\r\n/g, '\n')
    const { desc, keywords, realContent } = getMeta(fileContent)
    const title = file.replace('.md', '')
    const fileInfo = {
      id,  // id 是唯一的，此方式与服务端数据库生成方式不同
      cateId: category.id,
      title,
      content: realContent,
      metaDesc: desc,
      metaKeywords: keywords,
      createTime: moment(fileStat.birthtime).format('YYYY-MM-DD HH:mm:ss'),
      updateTime: moment(fileStat.mtime).format('YYYY-MM-DD HH:mm:ss')
    }

    lessInfo.push({ id, title })
    count++

    // 将文章具体信息写入到 /data/articles/articleId.json 中
    fs.writeFileSync(path.resolve(__dirname, DATA_DIR_NAME, 'articles', `${fileInfo.id}.json`)
      , JSON.stringify(fileInfo, null, 2)
    )
  })
  // 将读取到的简略分类文章信息写入到/data/cateArticleList/cateId.json中
  fs.writeFileSync(path.resolve(__dirname, DATA_DIR_NAME, 'cateArticleList', `${category.id}.json`)
    , JSON.stringify(lessInfo, null, 2))

  // 如果parentId不等于null，则说明它是个子分类，需要将 category 添加到对应的父分类中
  if (category.parentId !== null) {
    const parentCategory = categoryDesc.find(item => item.id === category.parentId)
    if (parentCategory) {
      if (!parentCategory.children) {
        parentCategory.children = []
      }
      parentCategory.children.push({
        id: category.id,
        title: category.title,
        count
      })
    }
  }
  // 保存文章数量到category中
  category.count = count
})

// 去除 categoryDesc 子项的 alias 字段
const categoryDescWithoutAlias = categoryDesc.map(category => {
  const { alias, ...rest } = category
  return rest
})
// 在 data 目录下的 cateList.json 文件中，将 categoryDesc 写入到文件中
fs.writeFileSync(path.resolve(__dirname, DATA_DIR_NAME, 'cateList.json')
  , JSON.stringify(categoryDescWithoutAlias, null, 2))


function getMeta(content) {
  // 文本的第一行是描述，第二行是关键字
  // 找到第一个换行符的位置
  const firstLineEnd = content.indexOf('\n')
  const firstLine = content.substring(0, firstLineEnd)
  if (!firstLine.startsWith(':D:')) {
    return { desc: '', keywords: '', realContent: content }
  }
  const desc = firstLine.substring(3)
  // 第二个换行符的位置
  const secondLineEnd = content.indexOf('\n', firstLineEnd + 1)
  const secondLine = content.substring(firstLineEnd + 1, secondLineEnd)
  if (!secondLine.startsWith(':K:')) {
    return { desc, keywords: '', realContent: content.substring(secondLineEnd + 1) }
  }
  const keywords = secondLine.substring(3)
  const realContent = content.substring(secondLineEnd + 1)
  return { desc, keywords, realContent }
}